package com.iplatform.commons.customGson;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

/**
 * Gson 反序列化
 * 自定义实现 java DateTime 转 String
 * @author houkunliang
 * @createDate 2019年3月7日
 */
public abstract class DynamicDateTypeAdapter extends TypeAdapter<Date> {

    private static final Map<String,DateFormat> DATE_FORMAT_MAP = new HashMap<>();

    private final String format;

    private DateFormat dateFormat;

    private static final DateFormat HHmm_DateFormat = new SimpleDateFormat("HH:mm",Locale.CHINA);
    private static final DateFormat yyyyMMdd_DateFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.CHINA);
    private static final DateFormat yyyyMMddHHmm_DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm",Locale.CHINA);
    private static final DateFormat yyyyMMddHHmmss_DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);


    protected DynamicDateTypeAdapter(@NonNull String format) {
        this.format = format;
        dateFormat = DATE_FORMAT_MAP.get(format);
        if(dateFormat == null){
            dateFormat = new SimpleDateFormat(format, Locale.CHINA);
            DATE_FORMAT_MAP.put(format,dateFormat);
        }
    }

    @Override
    public void write(JsonWriter out, Date value) throws IOException {
        if (value == null) {
            out.nullValue();
        } else {
        	/*System.out.println(dateFormat.format(value));
            out.jsonValue("123123");*/
            out.value(dateFormat.format(value));
        }
    }

    /**
     * 方法参数输入
     */
    @Override
    public Date read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        String jsonValue = in.nextString();
        // 4 HHmm
        // 8 yyyyMMdd
        // 12 yyyyMMddHHmm
        // 14 yyyyMMddHHmmss
        if ("19000101".equals(jsonValue)) {
            return null;
        }
        if ("190001010000".equals(jsonValue)) {
            return null;
        }

        if(StringUtils.isEmpty(jsonValue)){
            return null;
        }
        try {
            if(jsonValue.length() == 4){
                return HHmm_DateFormat.parse(jsonValue);
            }else if(jsonValue.length() == 8){
                return yyyyMMdd_DateFormat.parse(jsonValue);
            }else if(jsonValue.length() == 12){
                return yyyyMMddHHmm_DateFormat.parse(jsonValue);
            }else if(jsonValue.length() == 14){
                return yyyyMMddHHmmss_DateFormat.parse(jsonValue);
            }else{
                throw new IllegalArgumentException("unknown date date format, must be " + format);
            }
        } catch (ParseException e) {
            throw new IllegalArgumentException("unknown date date format, must be " + format, e);
        }
    }
}
